-
-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add "Remember Me" checkbox to the login form #440
Add "Remember Me" checkbox to the login form #440
Conversation
@haseebzaki-07 is attempting to deploy a commit to the bunty's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe pull request encompasses multiple changes across various files in the PlayCafe project. Key updates include modifications to the Changes
Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Thank you for submitting your pull request! 🙌 We'll review it as soon as possible. In the meantime, please ensure that your changes align with our CONTRIBUTING.md. If there are any specific instructions or feedback regarding your PR, we'll provide them here. Thanks again for your contribution! 😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 21
🧹 Outside diff range and nitpick comments (18)
backend/middlewares/sessionMiddleware.js (1)
5-8
: Consider adding error codes to the response.
While the JSON error response is good, adding an error code would help with error handling on the client side.
res.status(401).json({
success: false,
message: "Invalid session. Please log in again.",
+ errorCode: "SESSION_INVALID"
});
backend/models/reservation.model.js (1)
17-21
: Consider data migration strategy for existing reservations.
Since the new customer
field is marked as required, existing reservations in the database will need to be migrated to include this field.
Would you like me to help create a migration script or open an issue to track this task?
backend/routes/reservationRouter.js (2)
Line range hint 10-19
: Update API documentation to reflect new endpoints.
The welcome message's endpoints section is outdated. It still shows /create [POST]
but the actual endpoint is now /create/:id [POST]
. Additionally, the new /get/:id [GET]
endpoint is missing from the documentation.
Apply this diff to update the documentation:
endpoints: {
- createReservation: "/create [POST]",
+ createReservation: "/create/:id [POST]",
+ getUserReservations: "/get/:id [GET]"
},
7-8
: Consider rate limiting for reservation endpoints.
Since these endpoints are now authenticated per user, consider adding rate limiting to prevent abuse.
Consider implementing rate limiting middleware:
- Use
express-rate-limit
package - Set appropriate limits per user/IP
- Apply the middleware to these sensitive endpoints
Would you like me to provide an example implementation?
backend/routes/eventRouter.js (3)
31-31
: Consider keeping the /all route public.
The /all
route typically serves public event listings. Adding authentication might unnecessarily restrict access to event information that should be publicly available.
Consider maintaining this as a public route unless there's a specific requirement for authenticated access to event listings.
30-32
: Fix spacing in middleware chain.
There should be spaces after commas in the middleware chain for better readability.
Apply this formatting fix:
-router.post("/create",authenticateCustomer, createEvent);
-router.get("/all",authenticateCustomer, getEvents);
-router.get("/delete",authenticateCustomer, deleteEvent);
+router.post("/create", authenticateCustomer, createEvent);
+router.get("/all", authenticateCustomer, getEvents);
+router.get("/delete", authenticateCustomer, deleteEvent);
28-29
: Remove extra empty lines.
Multiple consecutive empty lines affect code readability.
Remove one of the empty lines to maintain consistent spacing.
backend/models/customer.model.js (1)
52-57
: New reservations field looks good but needs documentation.
The addition of the reservations field establishes a proper relationship with the Reservation model. However, consider adding JSDoc comments to document this relationship.
+ /**
+ * Array of reservations associated with this customer
+ * @type {Array<mongoose.Schema.Types.ObjectId>}
+ */
reservations: [
{
type: Schema.Types.ObjectId,
ref: "Reservation", // Link to Reservation schema
},
],
frontend/src/router/index.jsx (1)
25-25
: Consider aligning component naming with file naming.
The component is imported as Profile
from a file named Dashboard.tsx
. This naming inconsistency could lead to confusion. Consider either:
- Renaming the file to
Profile.tsx
to match the component name, or - Renaming the component to
Dashboard
to match the file name
backend/index.js (1)
Line range hint 47-54
: Consider updating session configuration for "Remember Me" feature.
The current session configuration has a fixed 24-hour cookie maxAge. For the "Remember Me" feature, consider implementing dynamic session duration:
- Short duration (e.g., 24 hours) for regular login
- Extended duration (e.g., 30 days) when "Remember Me" is checked
Example implementation:
app.use(
session({
secret: process.env.SECRET_KEY,
resave: false,
saveUninitialized: false,
cookie: {
// Make maxAge configurable based on "Remember Me"
maxAge: req?.body?.rememberMe ? 30 * 24 * 60 * 60 * 1000 : 24 * 60 * 60 * 1000,
secure: process.env.NODE_ENV === 'production',
},
store: MongoStore.create({
mongoUrl: process.env.MONGO_URI,
}),
})
);
frontend/src/components/Pages/Dashboard.tsx (2)
6-10
: Consider renaming the component to match the file name.
The component is named Profile
while the file is named Dashboard.tsx
. This inconsistency could lead to confusion. Consider renaming the component to Dashboard
to maintain consistency.
-function Profile() {
+function Dashboard() {
29-29
: Remove console.log statement.
Remove debugging console.log statement before production deployment.
- console.log("Decoded userId:", userId); // Debugging line
backend/controller/customer.controller.js (2)
115-123
: Consider minimizing the JWT payload.
While the implementation is functional, consider reducing the JWT payload size by including only essential claims. The email might not be necessary in the token if you're already storing the user ID.
const payload = {
sub: customer._id,
name: customer.name,
role: "customer",
- email: customer.email,
};
Line range hint 171-177
: Improve logout security for "Remember Me" sessions.
The current logout implementation using req.session.destroy()
doesn't invalidate the JWT token. Long-lived tokens from "Remember Me" sessions will remain valid until expiration.
Consider implementing one of these solutions:
- Add token to a blocklist/denylist on logout
- Use token rotation with refresh tokens
- Clear the auth cookie on logout
Here's how to properly clear the auth cookie:
async function logout(req, res){
- req.session.destroy((err) => {
- if (err) {
- return res.status(500).send("Failed to log out.");
- }
- res.send("Logged out successfully!");
- });
+ res.clearCookie('authToken', {
+ httpOnly: true,
+ secure: process.env.NODE_ENV === "production",
+ sameSite: "strict",
+ path: "/"
+ });
+ res.status(200).json({ message: "Logged out successfully" });
}
frontend/src/components/Shared/Navbar.jsx (2)
Line range hint 28-31
: Optimize useEffect to prevent unnecessary re-renders.
The useEffect hook without a dependency array will run on every render, which could cause performance issues. Consider adding an empty dependency array if you only want to run this once, or specific dependencies if you want to run it when certain values change.
useEffect(() => {
setToken(Cookies.get('authToken'));
- });
+ }, []);
Line range hint 11-11
: Consider enhancing token handling for Remember Me feature.
The current token management doesn't distinguish between regular and remembered tokens. To properly support the Remember Me feature:
- Consider adding a check for token expiration
- Handle token refresh if needed
- Ensure proper cleanup of both regular and remembered tokens during logout
Consider implementing a centralized auth service to handle these token management complexities. Example structure:
// auth.service.js
export const AuthService = {
getToken: () => {
const token = Cookies.get('authToken');
if (!token) return null;
// Add token validation/refresh logic here
return token;
},
logout: async () => {
// Clean up all auth-related cookies
Cookies.remove('authToken');
Cookies.remove('rememberMe');
// Additional cleanup as needed
}
};
Also applies to: 51-63
README.md (2)
Line range hint 283-503
: Replace hard tabs with spaces in the contributors table.
The contributors table uses hard tabs for indentation which is flagged by markdownlint. While this doesn't affect the rendered output, it's best practice to maintain consistent formatting.
Replace all hard tabs with spaces (2 or 4 spaces per indentation level) in the table structure.
🧰 Tools
🪛 Markdownlint
459-459: Column: 1
Hard tabs
(MD010, no-hard-tabs)
460-460: Column: 1
Hard tabs
(MD010, no-hard-tabs)
Line range hint 1-603
: Document the "Remember Me" feature in the README.
The PR adds a "Remember Me" checkbox to the login form, but this new feature is not documented in the README. Consider adding:
- A mention in the Features table
- Usage instructions in the Usage section
- Any relevant API endpoints in the API Documentation section
Add a new entry in the Features table:
| Feature | Description |
|-------------------------------|---------------------------------------------------------------|
+| 🔐 Remember Me | Stay logged in for extended periods with the Remember Me option|
Add usage instructions:
## 📌 Usage
Once the application is running, you can:
- Navigate through the website to explore different sections.
- Book a table for an event.
- Contact us for inquiries.
+- Use the "Remember Me" option during login to stay signed in.
Add API documentation:
| HTTP Method | Endpoint | Description |
|-------------|-----------------------|--------------------------------------------------------|
+| POST | `/api/auth/login` | Authenticates user with optional "Remember Me" duration |
🧰 Tools
🪛 Markdownlint
459-459: Column: 1
Hard tabs
(MD010, no-hard-tabs)
460-460: Column: 1
Hard tabs
(MD010, no-hard-tabs)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (17)
- README.md (7 hunks)
- backend/.env.example (0 hunks)
- backend/controller/customer.controller.js (2 hunks)
- backend/controller/reservation.controller.js (4 hunks)
- backend/index.js (1 hunks)
- backend/middlewares/authCustomer.js (1 hunks)
- backend/middlewares/sessionMiddleware.js (1 hunks)
- backend/models/customer.model.js (2 hunks)
- backend/models/reservation.model.js (1 hunks)
- backend/routes/eventRouter.js (2 hunks)
- backend/routes/reservationRouter.js (1 hunks)
- frontend/package.json (1 hunks)
- frontend/src/components/Pages/Dashboard.tsx (1 hunks)
- frontend/src/components/Pages/Event.jsx (3 hunks)
- frontend/src/components/Pages/Login.jsx (3 hunks)
- frontend/src/components/Shared/Navbar.jsx (1 hunks)
- frontend/src/router/index.jsx (2 hunks)
💤 Files with no reviewable changes (1)
- backend/.env.example
🧰 Additional context used
🪛 Markdownlint
README.md
283-283: Column: 1
Hard tabs
(MD010, no-hard-tabs)
284-284: Column: 1
Hard tabs
(MD010, no-hard-tabs)
327-327: Column: 1
Hard tabs
(MD010, no-hard-tabs)
328-328: Column: 1
Hard tabs
(MD010, no-hard-tabs)
371-371: Column: 1
Hard tabs
(MD010, no-hard-tabs)
372-372: Column: 1
Hard tabs
(MD010, no-hard-tabs)
459-459: Column: 1
Hard tabs
(MD010, no-hard-tabs)
460-460: Column: 1
Hard tabs
(MD010, no-hard-tabs)
503-503: Column: 1
Hard tabs
(MD010, no-hard-tabs)
504-504: Column: 1
Hard tabs
(MD010, no-hard-tabs)
🪛 Biome
backend/middlewares/sessionMiddleware.js
[error] 2-2: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (26)
backend/middlewares/sessionMiddleware.js (1)
1-12
: Verify integration with Remember Me functionality.
Since this middleware is part of the "Remember Me" feature implementation, ensure it properly handles extended session durations.
Let's check for session configuration and remember me implementation:
#!/bin/bash
# Look for session configuration
rg -A 5 "session\.(cookie|maxAge|expires)" --type js
# Look for remember me related code
rg -A 5 "rememberMe|remember_me" --type js
🧰 Tools
🪛 Biome
[error] 2-2: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
backend/models/reservation.model.js (1)
17-21
: LGTM! Well-structured schema relationship.
The addition of the customer
field with proper MongoDB/Mongoose relationship modeling looks good. The reference to the Customer model and required constraint ensures data integrity.
Let's verify the error handling in the controller:
✅ Verification successful
Error handling for customer field looks robust and complete
The controller implementation properly handles the required customer field with appropriate error handling:
- Validates customer existence before creating reservation
- Returns 404 if customer is not found
- Properly associates reservation with customer using
customer._id
- Includes comprehensive error logging
- Returns appropriate error responses with status codes
The implementation aligns well with the schema changes and handles the required customer field appropriately. No migration concerns as the controller ensures valid customer references for new reservations.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the reservation controller properly handles customer validation
# Look for error handling in the controller
rg -A 5 "createReservation|updateReservation" backend/controller/
Length of output: 724
Script:
#!/bin/bash
# Let's get more context around the reservation controller implementation
rg -B 5 -A 15 "createReservation.*try" backend/controller/reservation.controller.js
Length of output: 85
Script:
#!/bin/bash
# Let's try a different approach to get the controller implementation
cat backend/controller/reservation.controller.js
Length of output: 3871
backend/routes/reservationRouter.js (2)
2-2
: LGTM: Import statements are properly structured.
The new imports for fetchUserReservations
and authenticateCustomer
are correctly added and align with the route changes.
Also applies to: 4-4
7-8
: Verify error handling for invalid user IDs.
The new routes using :id
parameter need proper error handling for invalid user IDs.
Let's verify the error handling implementation:
#!/bin/bash
# Check if the controller handles invalid user IDs
ast-grep --pattern 'fetchUserReservations = async (req, res) => {
$$$
}'
# Check for error handling patterns in the controller
rg -A 5 "catch.*fetchUserReservations"
backend/routes/eventRouter.js (1)
8-8
: Verify error handling in the authentication middleware.
While adding authentication is a good security practice, we should ensure proper error handling in the middleware.
Let's check the error handling implementation:
✅ Verification successful
Error handling in authentication middleware is properly implemented
The middleware has comprehensive error handling with:
- Token presence check with 401 response
- Try-catch block for token verification
- Specific handling for expired tokens (401)
- Generic token verification errors (403)
- User existence check (404)
- Account verification status check (403)
- Proper logging of errors using the logger utility
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify error handling in authCustomer middleware
# Expected: Should find try-catch blocks and error responses
# Check the middleware implementation
rg -A 10 "const authenticateCustomer" backend/middlewares/authCustomer.js
Length of output: 417
Script:
#!/bin/bash
# Let's get the complete middleware implementation to verify error handling
rg -A 20 "const authenticateCustomer" backend/middlewares/authCustomer.js
# Also check for any custom error handling utilities that might be used
rg "catch|error" backend/middlewares/authCustomer.js
Length of output: 762
Script:
#!/bin/bash
# Let's verify if there's proper error response in the catch block
# and check if the middleware is properly exported
rg -A 5 "catch \(err\)" backend/middlewares/authCustomer.js
# Also check if logger is properly imported
rg "require.*logger|import.*logger" backend/middlewares/authCustomer.js
Length of output: 428
backend/models/customer.model.js (2)
24-31
: Formatting changes look good, but verify if intentional.
The removal of trailing commas in the otp
, otpExpiry
, and isVerified
fields maintains consistency with the rest of the schema.
#!/bin/bash
# Check if this is part of a larger formatting effort
rg -l ',$' --type js
Line range hint 1-63
: Missing schema fields for "Remember Me" functionality.
The PR objective is to implement a "Remember Me" feature, but the schema lacks necessary fields to support this functionality. Consider adding:
- A field for refresh tokens
- Token expiration timestamp
- Last login timestamp
Here's a suggested addition to the schema:
const customerSchema = new Schema(
{
// ... existing fields ...
+ refreshToken: {
+ type: String,
+ default: null
+ },
+ refreshTokenExpiry: {
+ type: Date,
+ default: null
+ },
+ lastLoginAt: {
+ type: Date,
+ default: null
+ },
// ... rest of the schema ...
},
{ timestamps: true }
);
frontend/package.json (2)
27-27
: LGTM! Note about jwt-decode security.
The addition of [email protected] aligns with the "Remember Me" feature implementation. Note that this library is for client-side token payload reading only and doesn't handle token validation, which is the correct approach as token validation should be performed server-side.
27-27
: Verify jwt-decode implementation.
Let's ensure the library is being used correctly in the codebase.
✅ Verification successful
Let me gather more information about how jwt-decode is actually used in the Dashboard component.
JWT-decode implementation is correctly used
The implementation in Dashboard.tsx follows security best practices:
- Only uses jwt-decode for reading the token payload (user ID)
- No client-side validation attempts
- Token verification is properly handled server-side (as seen in backend middlewares)
- Error handling is in place for decoding failures
- Token is properly passed in Authorization header for API requests
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check jwt-decode usage patterns to ensure correct implementation
# Test 1: Look for jwt-decode imports
echo "Checking jwt-decode import patterns..."
rg "import.*jwt-decode" -A 5
# Test 2: Look for potential direct token validation attempts
# (should be handled server-side)
echo "Checking for token validation patterns..."
rg "verify.*token|validate.*token|isValid.*token"
# Test 3: Look for token decoding usage
echo "Checking token decoding patterns..."
ast-grep --pattern 'jwtDecode($token)'
Length of output: 1050
Script:
#!/bin/bash
# Check the actual implementation in Dashboard.tsx
echo "Checking Dashboard.tsx implementation..."
cat frontend/src/components/Pages/Dashboard.tsx
# Look for any other files that might be using jwt-decode
echo -e "\nChecking for other jwt-decode usages..."
rg "jwtDecode" --type ts --type tsx
Length of output: 4093
frontend/src/router/index.jsx (1)
45-45
:
Add authentication guard for the dashboard route.
The dashboard route appears to handle user-specific data (reservations) but lacks authentication protection. This could expose sensitive information if accessed directly via URL.
Consider wrapping the route with an auth guard component:
- <Route path="/dashboard" element={<Profile />} />
+ <Route
+ path="/dashboard"
+ element={
+ <ProtectedRoute>
+ <Profile />
+ </ProtectedRoute>
+ }
+ />
Let's verify if other protected routes use authentication guards:
backend/index.js (2)
17-17
: CORS credentials configuration looks good but requires careful verification.
The addition of credentials: true
is necessary for the "Remember Me" feature to work with cookies across origins. The implementation is correct and origins are properly restricted.
Let's verify the CORS configuration is consistent across the codebase:
✅ Verification successful
CORS configuration is correctly and consistently implemented
The verification confirms that:
- There's a single
corsOptions
configuration withcredentials: true
properly set - This configuration is consistently used across all CORS middleware:
- Main CORS middleware:
app.use(cors(corsOptions))
- Global preflight:
app.options("*", cors(corsOptions))
- Commented route-specific preflight also references the same config
- Main CORS middleware:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any other CORS configurations that might need credentials
# Test: Search for CORS configurations. Expect: All CORS configs to have credentials option set
rg -B 2 -A 2 "cors\("
Length of output: 598
Script:
#!/bin/bash
# Let's check the corsOptions configuration to ensure it's properly defined
rg -B 5 -A 5 "corsOptions\s*="
Length of output: 539
Line range hint 7-7
: Fix typo in error middleware import path.
The import statement contains a typo: errrorMiddleware
(three 'r's) should be errorMiddleware
.
Let's verify the correct middleware file name and its usage:
Apply this fix:
-const errorMiddleware = require("./middlewares/errrorMiddleware");
+const errorMiddleware = require("./middlewares/errorMiddleware");
frontend/src/components/Pages/Dashboard.tsx (2)
1-5
: LGTM! Imports and environment setup are well structured.
The necessary dependencies are properly imported and the environment variable usage follows best practices.
Also applies to: 11-11
1-112
: Verify PR scope and objectives.
This file implements a dashboard/profile view for displaying user reservations, but it appears unrelated to the "Remember Me" checkbox functionality mentioned in the PR objectives. Please clarify if this file should be part of this PR or if it should be moved to a separate PR focused on user dashboard functionality.
frontend/src/components/Pages/Login.jsx (1)
25-35
:
Implement additional security measures
The login implementation needs several security enhancements:
- Add CSRF protection
- Implement rate limiting for failed attempts
- Use more specific error messages without leaking sensitive information
try {
const response = await fetch(`${API_URL}/api/user/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
+ 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content,
},
body: JSON.stringify({ ...data, rememberMe }),
});
const result = await response.json();
- if (!response.ok) throw new Error(result.message || 'Login failed');
+ if (!response.ok) {
+ switch (response.status) {
+ case 401:
+ throw new Error('Invalid email or password');
+ case 429:
+ throw new Error('Too many login attempts. Please try again later');
+ default:
+ throw new Error('An error occurred during login');
+ }
+ }
backend/controller/customer.controller.js (2)
90-90
: LGTM: Schema update for rememberMe is well-defined.
The optional boolean field is correctly added to the schema with proper type validation.
99-101
: LGTM: Clean parameter extraction with proper validation.
The destructuring is performed after schema validation, ensuring type safety.
frontend/src/components/Shared/Navbar.jsx (1)
25-25
: Verify the dashboard route implementation.
The new PROFILE menu item links to /dashboard
. Please ensure that this route is properly configured in your routing setup and that the Dashboard component is implemented.
✅ Verification successful
Let me verify the route configuration with a corrected regex pattern.
Let me check the routing configuration with a corrected command and also verify the component imports.
Let me check the App.jsx for route configuration and examine the component naming discrepancy.
The dashboard route and component implementation are verified, but there's a naming inconsistency.
The /dashboard
route is properly configured in router/index.jsx
and maps to the Profile component. However, there are some confusing naming patterns:
- The component is named
Profile
but lives inDashboard.tsx
- The route is
/dashboard
but imports a component namedProfile
- The navbar menu item is labeled 'PROFILE' but uses
/dashboard
path
While functionally correct, consider renaming for better consistency:
- Either rename the file to
Profile.tsx
to match the component name - Or rename the component to
Dashboard
to match the file and route
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for dashboard route configuration
rg -l "path.*['\"]\/dashboard['\"]" --type js --type jsx --type ts --type tsx
# Search for Dashboard component
fd -e jsx -e tsx -e js -e ts "Dashboard"
Length of output: 270
Script:
#!/bin/bash
# Search for dashboard route configuration with corrected pattern
rg -l 'path.*["\'']/dashboard' --type js --type jsx --type ts --type tsx
# Check the route configuration in common routing files
rg -A 5 'Route.*dashboard' --type js --type jsx --type ts --type tsx
# Examine Dashboard component implementation
cat frontend/src/components/Pages/Dashboard.tsx
Length of output: 4103
Script:
#!/bin/bash
# Search for route configurations with fixed pattern
rg -l "/dashboard" --type js --type jsx --type ts --type tsx
# Check App.tsx or similar files for routing
fd -e tsx -e jsx "App"
# Check if the Profile component is properly imported where routes are defined
rg -l "import.*Profile" --type js --type jsx --type ts --type tsx
Length of output: 228
Script:
#!/bin/bash
# Examine App.jsx content for route configuration
cat frontend/src/App.jsx
# Search for Dashboard/Profile imports and usage with text-based search
rg "Dashboard|Profile" --type-add 'web:*.{js,jsx,ts,tsx}' -t web
Length of output: 879
frontend/src/components/Pages/Event.jsx (3)
17-18
: LGTM: Required imports added correctly.
The new imports for navigation and cookie management are appropriately placed and necessary for the authentication feature.
36-36
: LGTM: Navigation hook initialized correctly.
The useNavigate hook is properly initialized following React hooks best practices.
Line range hint 17-45
: Verify integration with login page's "Remember Me" feature.
The current implementation checks for the authentication token but should be tested with the login page's "Remember Me" functionality to ensure proper integration.
✅ Verification successful
Integration with "Remember Me" feature is properly implemented
The verification shows that:
- Login.jsx correctly implements the "Remember Me" functionality with proper cookie expiration handling (7 days if checked, 1 hour if not)
- Event.jsx's authentication check aligns with the cookie-based auth system
- Cookie handling is consistent across components (Login, Event, Navbar, Dashboard)
The implementation in Event.jsx is appropriate and works correctly with the "Remember Me" feature from the login page.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the integration between Event.jsx and Login page
# Check if Login page implements Remember Me checkbox
echo "Checking for Remember Me implementation in Login page..."
rg -l "Remember Me" "frontend/src/components/Pages/Login"
# Check for consistent token handling
echo "Checking token handling consistency..."
rg "Cookies\.(get|set|remove)\('authToken'\)" "frontend/src/**/*.{jsx,js,tsx,ts}"
Length of output: 507
Script:
#!/bin/bash
# Let's first find the correct paths for Login and Event components
echo "Finding Login and Event component files..."
fd -e jsx -e js "Login|Event"
# Then check for Remember Me and cookie handling
echo "Checking for Remember Me implementation..."
rg -i "remember me"
echo "Checking cookie handling across files..."
rg "Cookies\.(get|set|remove)\('authToken'\)"
Length of output: 1388
backend/middlewares/authCustomer.js (3)
20-21
: Avoid revealing user existence to prevent enumeration attacks
Returning a 404 status with "User not found" may inadvertently disclose whether a user exists, potentially aiding in user enumeration attacks. It's more secure to return a generic authentication error.
[security_issue]
Consider responding with a generic authentication failure:
- return res.status(404).json({ message: "User not found" });
+ return res.status(401).json({ message: "Authentication failed" });
23-25
: Prevent account verification status disclosure for enhanced security
Informing the client that the account is not verified can help attackers identify valid user accounts. To mitigate this risk, consider returning a generic error message instead.
[security_issue]
Modify the response to be less specific:
- return res.status(403).json({ message: "Account not verified" });
+ return res.status(401).json({ message: "Authentication failed" });
28-28
: Verify that 'user.name' exists in the Customer model
Ensure that the Customer
model includes a name
property. If user.name
is undefined, the log message will be incomplete or misleading.
Run the following script to check if name
exists in the Customer
model:
✅ Verification successful
The name
property is properly defined in the Customer model
The verification confirms that the Customer model (backend/models/customer.model.js
) includes a name
property of type String that is marked as required, making it safe to use user.name
in the log message.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if 'name' property exists in the Customer model
# Find the Customer model file and search for 'name' property definition
fd 'customer.model.js' | while read file; do
echo "Checking $file"
rg 'name' "$file"
done
Length of output: 226
backend/controller/reservation.controller.js (2)
33-40
:
Ensure authorized users can only create reservations for themselves.
There's no check to verify that the authenticated user matches the userId
in the request parameters. Without this check, a user could potentially create a reservation on behalf of another user.
Consider adding an authorization check:
const userId = req.params.id
+ if (req.user.id !== userId) {
+ return res.status(403).json({
+ success: false,
+ message: "You are not authorized to create a reservation for this user.",
+ });
+ }
const customer = await Customer.findById(userId);
91-129
:
Implement authorization check when fetching user reservations.
The fetchUserReservations
function lacks an authorization mechanism to ensure the requesting user is permitted to access the specified user's reservations. This could lead to unauthorized access to other users' data.
Consider adding an authorization check:
const userId = req.params.id; // Extract user ID from route parameters
+ if (req.user.id !== userId) {
+ return res.status(403).json({
+ success: false,
+ message: "You are not authorized to access these reservations.",
+ });
+ }
const reservations = await Reservation.find({ customer: userId }).populate("customer", "name email");
const sessionMiddleware = (req, res, next) => { | ||
if (req.session.user && req.session.user.id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using optional chaining for safer property access.
The session validation can be written more concisely using optional chaining.
- if (req.session.user && req.session.user.id) {
+ if (req?.session?.user?.id) {
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const sessionMiddleware = (req, res, next) => { | |
if (req.session.user && req.session.user.id) { | |
const sessionMiddleware = (req, res, next) => { | |
if (req?.session?.user?.id) { |
🧰 Tools
🪛 Biome
[error] 2-2: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
const sessionMiddleware = (req, res, next) => { | ||
if (req.session.user && req.session.user.id) { | ||
next(); // Continue if session is valid and has user ID | ||
} else { | ||
res.status(401).send("Invalid session. Please log in again."); | ||
res.status(401).json({ | ||
success: false, | ||
message: "Invalid session. Please log in again.", | ||
}); | ||
} | ||
} | ||
|
||
module.exports = sessionMiddleware; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Security enhancements needed for session management
The verification reveals several security gaps that support the original review comment:
- No CSRF protection is implemented in the codebase
- Session configuration has security weaknesses:
secure: false
in session cookie configuration- No explicit
sameSite
attribute in session cookies
- No type validation for
user.id
in the session middleware - While "Remember Me" functionality is implemented with proper expiration times, the session security measures aren't adequately strengthened to support it
Recommendations:
- Add CSRF middleware (e.g.,
csurf
package) - Enable
secure: true
for session cookies in production - Add
sameSite: 'strict'
to session cookie configuration - Implement type checking for
user.id
- Consider adding
helmet
middleware for additional security headers
🔗 Analysis chain
Enhance session security measures.
The current session validation could be strengthened by:
- Adding type checking for user.id
- Implementing session expiration checks
- Adding CSRF protection
This is particularly important given the new "Remember Me" functionality being implemented.
Let's verify if CSRF protection is implemented elsewhere:
Let me gather more information about the session and security configurations.
Let me check for additional security configurations and session settings.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for CSRF middleware or protection
rg -i "csrf|csurf" --type js
Length of output: 3678
Script:
#!/bin/bash
# Check for session configuration and security measures
rg -A 5 'app\.use.*session|express-session|cookie-parser|helmet|cors' --type js
# Check for type validation of user.id
ast-grep --pattern 'user.id'
Length of output: 1606
Script:
#!/bin/bash
# Check for session configuration details and security middleware
rg -A 10 'session\(' --type js
# Look for security-related middleware and configurations
rg -A 5 'helmet|secure|sameSite|httpOnly' --type js
Length of output: 2634
🧰 Tools
🪛 Biome
[error] 2-2: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
router.post("/create/:id", authenticateCustomer, createReservation); | ||
router.get("/get/:id", authenticateCustomer, fetchUserReservations); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Remove unused sessionMiddleware
import
The codebase shows a clear transition from session-based authentication to JWT-based authentication:
- The reservation routes exclusively use
authenticateCustomer
middleware - While
sessionMiddleware
is still actively used in other routes (feedback, order), it's not used in this file - The authentication system uses
passport.authenticate("jwt", { session: false })
indicating JWT-based auth
Remove the unused import:
-const sessionMiddleware = require("../middlewares/sessionMiddleware");
🔗 Analysis chain
Verify session handling with new authentication flow.
The routes now use authenticateCustomer
but still import unused sessionMiddleware
. This suggests a potential transition in the authentication mechanism.
Let's check for any remaining uses of sessionMiddleware
:
If sessionMiddleware
is no longer used, remove the unused import:
-const sessionMiddleware = require("../middlewares/sessionMiddleware");
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for other uses of sessionMiddleware in the codebase
rg "sessionMiddleware" --type js
Length of output: 117
Script:
#!/bin/bash
# Let's first check if sessionMiddleware is imported in the file
rg -A 2 "require.*sessionMiddleware" backend/routes/reservationRouter.js
# Check for any session-related middleware or authentication across the codebase
rg "session" --type js
# Let's also verify the imports in the router file
head -n 10 backend/routes/reservationRouter.js
Length of output: 2318
|
||
router.post("/create",authenticateCustomer, createEvent); | ||
router.get("/all",authenticateCustomer, getEvents); | ||
router.get("/delete",authenticateCustomer, deleteEvent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use DELETE HTTP method for delete operations.
The delete route currently uses GET method which doesn't follow REST conventions. DELETE operations should use the DELETE HTTP method.
Apply this change:
-router.get("/delete", authenticateCustomer, deleteEvent);
+router.delete("/delete", authenticateCustomer, deleteEvent);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
router.get("/delete",authenticateCustomer, deleteEvent); | |
router.delete("/delete",authenticateCustomer, deleteEvent); |
try { | ||
const response = await fetch( | ||
`${API_URL}/api/reservation/get/${userId}`, | ||
{ | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'Authorization': `Bearer ${authToken}`, // Pass the token in headers | ||
}, | ||
credentials: 'include', | ||
} | ||
); | ||
|
||
if (!response.ok) { | ||
const errorData = await response.json(); | ||
throw new Error(errorData.message || 'Failed to fetch reservations'); | ||
} | ||
|
||
const data = await response.json(); | ||
setReservations(data.data); | ||
} catch (error) { | ||
setError(error.message); | ||
console.error('Error fetching reservations:', error); | ||
} finally { | ||
setLoading(false); // Set loading to false after the fetch operation | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error handling and API URL construction.
- The error handling could be more specific to different types of errors (network, auth, etc.).
- Consider moving the API endpoint construction to a separate constant or utility.
+ const ENDPOINTS = {
+ GET_RESERVATIONS: (userId: string) => `${API_URL}/api/reservation/get/${userId}`,
+ };
+
try {
const response = await fetch(
- `${API_URL}/api/reservation/get/${userId}`,
+ ENDPOINTS.GET_RESERVATIONS(userId),
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${authToken}`,
},
credentials: 'include',
}
);
if (!response.ok) {
+ if (response.status === 401) {
+ throw new Error('Authentication expired. Please login again.');
+ }
+ if (response.status === 404) {
+ throw new Error('No reservations found for this user.');
+ }
const errorData = await response.json();
throw new Error(errorData.message || 'Failed to fetch reservations');
}
Committable suggestion was skipped due to low confidence.
const user = await Customer.findById(decoded.sub); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Handle invalid user IDs to prevent potential errors
If decoded.sub
contains an invalid user ID format, Customer.findById(decoded.sub)
may throw an error or return null
. It's advisable to handle this scenario explicitly to prevent unexpected behavior.
Consider adding error handling around the database query:
const user = await Customer.findById(decoded.sub);
+ if (user === null) {
+ return res.status(404).json({ message: "User not found" });
+ }
Committable suggestion was skipped due to low confidence.
const token = req.header("Authorization")?.split(" ")[1]; | ||
|
||
if (!token) { | ||
return res.status(401).json({ message: "Authorization token is missing" }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle malformed or missing 'Authorization' header to prevent errors
If the Authorization
header is missing or doesn't contain a token in the expected format, split(" ")[1]
may result in undefined
, leading to unexpected behavior. It's important to handle cases where the header is malformed to improve robustness.
Consider modifying the token extraction and adding checks:
- const token = req.header("Authorization")?.split(" ")[1];
+ const authHeader = req.header("Authorization");
+ if (!authHeader) {
+ return res.status(401).json({ message: "Authorization header is missing" });
+ }
+ const tokenParts = authHeader.split(" ");
+ if (tokenParts[0] !== "Bearer" || !tokenParts[1]) {
+ return res.status(401).json({ message: "Authorization token is missing or malformed" });
+ }
+ const token = tokenParts[1];
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const token = req.header("Authorization")?.split(" ")[1]; | |
if (!token) { | |
return res.status(401).json({ message: "Authorization token is missing" }); | |
} | |
const authHeader = req.header("Authorization"); | |
if (!authHeader) { | |
return res.status(401).json({ message: "Authorization header is missing" }); | |
} | |
const tokenParts = authHeader.split(" "); | |
if (tokenParts[0] !== "Bearer" || !tokenParts[1]) { | |
return res.status(401).json({ message: "Authorization token is missing or malformed" }); | |
} | |
const token = tokenParts[1]; | |
if (!token) { | |
return res.status(401).json({ message: "Authorization token is missing" }); | |
} |
if (err.name === "TokenExpiredError") { | ||
return res.status(401).json({ message: "Token expired" }); | ||
} | ||
logger.error("Token verification failed:", err); | ||
return res.status(403).json({ message: "Invalid token" }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance error handling for JWT verification failures
Currently, only TokenExpiredError
is specifically handled. Other JWT errors, such as JsonWebTokenError
and NotBeforeError
, could occur. Handling these errors can provide clearer feedback to the client.
Update the error handling to cover additional JWT errors:
if (err.name === "TokenExpiredError") {
return res.status(401).json({ message: "Token expired" });
+ } else if (err.name === "JsonWebTokenError") {
+ return res.status(403).json({ message: "Invalid token" });
+ } else if (err.name === "NotBeforeError") {
+ return res.status(403).json({ message: "Token not active" });
} else {
logger.error("Token verification failed:", err);
return res.status(403).json({ message: "Invalid token" });
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (err.name === "TokenExpiredError") { | |
return res.status(401).json({ message: "Token expired" }); | |
} | |
logger.error("Token verification failed:", err); | |
return res.status(403).json({ message: "Invalid token" }); | |
if (err.name === "TokenExpiredError") { | |
return res.status(401).json({ message: "Token expired" }); | |
} else if (err.name === "JsonWebTokenError") { | |
return res.status(403).json({ message: "Invalid token" }); | |
} else if (err.name === "NotBeforeError") { | |
return res.status(403).json({ message: "Token not active" }); | |
} else { | |
logger.error("Token verification failed:", err); | |
return res.status(403).json({ message: "Invalid token" }); | |
} |
|
||
// Create the reservation in the database | ||
const reservation = await Reservation.create(validationResult.data); | ||
const { email, date, guests, time } = validationResult.data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the customer's email from the database instead of the request body.
Using email
from the request body can be a security risk, as it allows sending confirmation emails to arbitrary addresses. To prevent potential misuse, obtain the customer's email from the database record.
Apply this diff to use the customer's email:
const { date, guests, time } = validationResult.data;
+ const email = customer.email;
...
await sendReservationConfirmation(email, {
reservationDate: date,
guests,
time,
});
Also applies to: 56-61
time: z.string(), | ||
email: z.string().email(), // Include email validation in the schema | ||
email: z.string().email(), // Include email validation | ||
userId: z.string().optional(), // Make userId optional for validation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove userId
from the validation schema if it's not used from req.body
.
The userId
field is included in the reservationSchema
but is not utilized from req.body
in the createReservation
function. Including it in the schema could lead to confusion and is unnecessary since userId
is extracted from req.params.id
.
Apply this diff to remove userId
from the validation schema:
email: z.string().email(), // Include email validation
- userId: z.string().optional(), // Make userId optional for validation
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
time: z.string(), | |
email: z.string().email(), // Include email validation in the schema | |
email: z.string().email(), // Include email validation | |
userId: z.string().optional(), // Make userId optional for validation | |
time: z.string(), | |
email: z.string().email(), // Include email validation |
@haseebzaki-07 resolve the conflicts |
@RamakrushnaBiswal done |
f5617e3
into
RamakrushnaBiswal:main
fixes #276
This PR adds the remember me feature while logging in so that the token can be set for a longer duration.
Modifications in the login controller and the login frontend page.
2024-10-30.16-49-05.mp4
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Documentation
Chores
Style